001 /* EVolve - an Extensible Software Visualization Framework
002 * Copyright (C) 2001-2002 Qin Wang
003 *
004 * This library is free software; you can redistribute it and/or
005 * modify it under the terms of the GNU Library General Public
006 * License as published by the Free Software Foundation; either
007 * version 2 of the License, or (at your option) any later version.
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Library General Public License for more details.
013 *
014 * You should have received a copy of the GNU Library General Public
015 * License along with this library; if not, write to the
016 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017 * Boston, MA 02111-1307, USA.
018 */
019
020 /*
021 * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022 */
023
024 package EVolve.visualization;
025
026 import EVolve.exceptions.NoDataPlotException;
027
028 import java.awt.*;
029 import java.awt.image.*;
030 import java.util.*;
031
032 /**
033 * Automatic expanding image.
034 */
035 public class AutoImage implements Cloneable{
036 protected short[][] image; // the image
037 protected int w, h; // width and height of the content
038 protected int wMax, hMax; // width and height of the image
039 protected int imageWidth, imageHeight;
040
041 protected HashMap object2Int,Int2Object;
042
043 /**
044 * Creates an auto-image.
045 */
046 public AutoImage() {
047 w = 0;
048 h = 0;
049 wMax = 200;
050 hMax = 200;
051 image = new short[wMax][hMax];
052 for (int i = 0; i < wMax; i++) {
053 for (int j = 0; j < hMax; j++) {
054 image[i][j] = 0;
055 }
056 }
057 object2Int = new HashMap();
058 Int2Object = new HashMap();
059 object2Int.put(null,new Integer(0));
060 Int2Object.put(new Integer(0),null);
061 }
062
063 /**
064 * Sets the color of a pixel.
065 *
066 * @param x position on X-axis
067 * @param y position on Y-axis
068 * @param color the color
069 */
070 public void setColor(int x, int y, Object color) {
071 if ((x >= wMax) || (y >= hMax)) {
072 while (x >= wMax) {
073 wMax += 200;
074 }
075 while (y >= hMax) {
076 hMax += 200;
077 }
078
079 short[][] newImage = new short[wMax][hMax];
080 for (int i = 0; i < wMax; i++) {
081 for (int j = 0; j < hMax; j++) {
082 newImage[i][j] = 0;
083 }
084 }
085 for (int i = 0; i < w; i++) {
086 for (int j = 0; j < h; j++) {
087 newImage[i][j] = image[i][j];
088 }
089 }
090 image = newImage;
091 }
092
093 if (object2Int.containsKey(color)) {
094 image[x][y] = ((Integer)object2Int.get(color)).shortValue();
095 } else {
096 short size = (short)object2Int.size();
097 object2Int.put(color,new Integer(size));
098 Int2Object.put(new Integer(size),color);
099 image[x][y] = size;
100 }
101
102 if (x >= w) {
103 w = x + 1;
104 }
105 if (y >= h) {
106 h = y + 1;
107 }
108 }
109
110 /**
111 * Gets the color of a pixel.
112 *
113 * @param x position on X-axis
114 * @param y position on Y-axis
115 * @return the color
116 */
117 public Object getColor(int x, int y) {
118 if ((image!=null) && ((x < 0) || (y < 0) || (x >= image.length) || (y >= image[0].length))) {
119 return null;
120 } else {
121 int index = image[x][y];
122 return Int2Object.get(new Integer(index));
123 }
124 }
125
126 public Color getSortedColor(ReferenceDimension xAxis, ReferenceDimension yAxis,int x,int y) {
127 int xMappedId,yMappedId;
128 xMappedId = (xAxis == null) ? x : xAxis.getOriginMappedId(x);
129 yMappedId = (yAxis == null) ? y : yAxis.getOriginMappedId(y);
130
131 if ((xMappedId >= wMax) || (yMappedId >= hMax) || (xMappedId < 0) || (yMappedId < 0))
132 return null;
133 else {
134 int index = image[xMappedId][yMappedId];
135 if (index == 0)
136 return null;
137 else
138 return (Color)Int2Object.get(new Integer(index));
139 }
140 }
141
142 /**
143 * Gets the buffered-image.
144 *
145 * @return buffered-image
146 */
147 public BufferedImage getImage() throws NoDataPlotException {
148
149 if (w*h == 0) throw new NoDataPlotException();
150
151 BufferedImage returnVal = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
152 returnVal.getGraphics().setColor(Color.white);
153 returnVal.getGraphics().fillRect(0, 0, w, h);
154
155 for (int i = 0; i < w; i++) {
156 for (int j = 0; j < h; j++) {
157 if (image[i][j] != 0) {
158 returnVal.setRGB(i, j, ((Color)Int2Object.get(new Integer(image[i][j]))).getRGB());
159 }
160 }
161 }
162
163 return returnVal;
164 }
165
166 /**
167 * Sorts the image.
168 *
169 * @param xAxis dimension that represents the X-axis, null if doesn't need to be sorted
170 * @param yAxis dimension that represents the Y-axis, null if doesn't need to be sorted
171 * @return sorted image
172 */
173 public AutoImage getSortedImage(ReferenceDimension xAxis, ReferenceDimension yAxis) {
174 AutoImage returnVal = new AutoImage();
175 for (int i = 0; i < w; i++) {
176 for (int j = 0; j < h; j++) {
177 int x, y;
178 if (xAxis == null) {
179 x = i;
180 } else {
181 x = xAxis.getSortedIndex(i);
182 }
183 if (yAxis == null) {
184 y = j;
185 } else {
186 y = yAxis.getSortedIndex(j);
187 }
188 if ((x != -1) && (y != -1)) {
189 returnVal.setColor(x, y, Int2Object.get(new Integer(image[i][j])));
190 }
191 }
192 }
193 return returnVal;
194 }
195
196 public int getDimension(int dim) {
197 if (dim == -1) return image.length;
198
199 return image[dim].length;
200 }
201
202 public int getW() {
203 return w;
204 }
205
206 public int getH() {
207 return h;
208 }
209
210 public void setImageWidth(int width, int height) {
211 imageWidth = w;
212 imageHeight = h;
213 }
214
215 public short[][] getImageDataArray() {
216 return image;
217 }
218
219 public Object clone() {
220 AutoImage o = null;
221 try {
222 o = (AutoImage)super.clone();
223 } catch (CloneNotSupportedException e) {
224 e.printStackTrace();
225 return o;
226 }
227
228 o.Int2Object = new HashMap();
229 o.object2Int = new HashMap();
230 o.object2Int.put(null,new Integer(0));
231 o.Int2Object.put(new Integer(0),null);
232 o.image = new short[image.length][];
233 for (int i=0; i<image.length; i++) {
234 o.image[i] = new short[image[i].length];
235 for (int j=0; j<image[i].length; j++) {
236 o.image[i][j] = image[i][j];
237 }
238 }
239 Iterator it = object2Int.keySet().iterator();
240 while (it.hasNext()) {
241 Object key = it.next();
242 o.object2Int.put(key, object2Int.get(key));
243 }
244 it = Int2Object.keySet().iterator();
245 while (it.hasNext()) {
246 Object key = it.next();
247 o.Int2Object.put(key, Int2Object.get(key));
248 }
249 return o;
250 }
251 }